<?php

namespace Remoteshell\PhpBotSdk\webhook;

use Katzgrau\KLogger\Logger;
use phpbotsdk\encryptor\LinuxEncryptor;
use phpbotsdk\encryptor\Main;
use Remoteshell\PhpBotSdk\logger\LoggerRecoder;

/**
 * WEBHOOK访问类
 * @class WebHookAccess
 */
class WebHookAccess
{
    private static string $secret;
    private static string $appid;

    private LoggerRecoder $logger;

    private string $authorID;

    private string $memberOpenID;

    private string $unionID;

    private string $groupID;
    private string $groupOpenID;
    private string $source;
    private string $callBackData;
    private string $event_type;

    /**
     * @param string $secret
     * @param string $app_id
     */
    public function __construct(string $secret, string $app_id)
    {
        self::$secret = $secret;
        self::$appid = $app_id;
    }

    /**
     * @return void
     * 效验签名算法
     */
    public function Signature(): void
    {
        // 获取请求头
        $this->logger = new LoggerRecoder();
        $headers = getallheaders();
        if (isset($headers['User-Agent']) && isset($headers['X-Bot-Appid'])) {
            if ($headers['User-Agent'] == "QQBot-Callback" && $headers['X-Bot-Appid'] == self::$appid) {
                $json = file_get_contents("php://input");
                $data = json_decode($json, true);
                $this->logger->record("normal", json_encode($data, JSON_PRETTY_PRINT));

                $os = php_uname('s');
                if (isset($data['d']['plain_token']) && isset($data['d']['event_ts']) && $os == 'Linux') {
                    new LinuxEncryptor(self::$secret, $data['d']['event_ts'], $data['d']['plain_token']);
                    header('Content-Type: application/json');
                    $result = LinuxEncryptor::encrypt();
                    echo json_encode([
                        "plain_token" => $data['d']['plain_token'],
                        "signature" => $result,
                    ]);
                } elseif (isset($data['d']['plain_token']) && isset($data['d']['event_ts']) && $os == 'Windows NT') {
                    new Main(self::$secret, $data['d']['event_ts'], $data['d']['plain_token']);
                    header('Content-Type: application/json');
                    $result = Main::encrypt();
                    echo json_encode([
                        "plain_token" => $data['d']['plain_token'],
                        "signature" => $result,
                    ]);
                }
            } else {
                $this->logger->record("error", "Invalid User-Agent or X-Bot-Appid");
            }
        }
    }

    /**
     * 解析回调接口发来的数据
     * @return array
     */
    public function AnalysisDataFromCallBackInterface(): array
    {
        $json = file_get_contents("php://input");
        $decode_data = json_decode($json, true);
        $this->logger->record("normal", "Received: " . json_encode($decode_data, JSON_PRETTY_PRINT). "\n");
        if (isset($decode_data['op']) && isset($decode_data['id'])) {
            if (isset($decode_data['d'])) {
                $payLoadD = $decode_data['d'];
                $id = $payLoadD['id'];
                $content = $payLoadD['content'];
                $timestamp = $payLoadD['timestamp'];
                if (!isset($timestamp) || !isset($content)) {
                    $this->logger->record("error", "Invalid Time Stamp! or contents");
                } elseif (!isset($id)) {
                    $this->logger->record("error", "Invalid ID");
                }

                if (isset($payLoadD['author'])) {
                    $author = $payLoadD['author'];
                    $this->authorID = $author['id'];
                    $this->memberOpenID = $author['member_openid'];
                    $this->unionID = $author['union_openid'];
                }

                if (!isset($payLoadD['group_id']) || !isset($payLoadD['group_openid'])) {
                    $this->logger->record("error", "Invalid Group ID or Group OpenID");
                } else {
                    $this->groupID = $payLoadD['group_id'];
                    $this->groupOpenID = $payLoadD['group_openid'];
                }

                if (!isset($payLoadD['message_scene'])){
                    $this->logger->record("error", "Invalid Message Scene");
                } else {
                    $messageScene = $payLoadD['message_scene'];
                    $this->source = $messageScene['source'];
                    $this->callBackData = $messageScene['callback_data'];
                }

                if (isset($decode_data['t'])){
                    $this->event_type = $decode_data['t'];
                } else {
                    $this->logger->record("error", "Invalid Event Type");
                }
            } else {
                $this->logger->record("error", "Invalid PayLoad Data");
            }
        } else {
            $this->logger->record("error", "Invalid OP or ID");
        }
        return [
            "operand" => $decode_data['op'],
            "id" => $id,
            "contents" => $content,
            "timestamp" => $timestamp,
            "author_id" => $this->authorID,
            "member_openid" => $this->memberOpenID,
            "union_id" => $this->unionID,
            "group_id" => $this->groupID,
            "group_openid" => $this->groupOpenID,
            "source" => $this->source,
            "callback_data" => $this->callBackData,
            "event_type" => $this->event_type,
        ];
    }

    /**
     * @return array
     */
    public static function getUserBasicInfo()
    {
        return [
            'appid' => json_decode('../../user_config.json')['appid'],
            'secret' => json_decode('../../user_config.json')['secret']
        ];
    }
}